package Model;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Observable;

/**
 * class used to represent a whole clan
 */
public class Clan extends Observable {
    // ATTRIBUTE

    private String name;
    private HashMap<Integer, Villager> villagerList;
    private HashMap<Integer, Building> buildingList;
    ArrayList<Resource> resourceList;
    private Square squareQG;
    private Memory clanMemory;
    private Board board;

    // CONSTRUCTOR
    public Clan() {
        this.name = "DefaultClan";
        this.villagerList = new HashMap<Integer, Villager>();
        this.buildingList = new HashMap<Integer, Building>();
        this.resourceList = new ArrayList<Resource>();
        this.clanMemory = new Memory();
    }

    public Clan(String name, Square qg) {
        this.name = name;
        this.squareQG = qg;
        this.villagerList = new HashMap<Integer, Villager>();
        this.buildingList = new HashMap<Integer, Building>();
        this.resourceList = new ArrayList<Resource>();
    }

    public Clan(String name, Square qg, Board board) {
        this.name = name;
        this.squareQG = qg;
        this.villagerList = new HashMap<Integer, Villager>();
        this.buildingList = new HashMap<Integer, Building>();
        this.resourceList = new ArrayList<Resource>();
        this.board = board;
        this.clanMemory = new Memory();
    }

    public void dropFood(Villager v) {
        ResourceType resourceType = v.getResourceBrought().getType();

        Resource clanResource = null;

        for (Resource i : resourceList) {
            if (resourceType.equals(i.getType())) {
                clanResource = i;
                break;
            }
        }

        if (clanResource == null) {
            clanResource = new Resource(resourceType, v.getResourceBrought().getAmount());
            resourceList.add(clanResource);
            v.getResourceBrought().setAmount(0);

        } else {
            clanResource.setAmount(clanResource.getAmount() + v.getResourceBrought().getAmount());
            v.getResourceBrought().setAmount(0);
        }

        this.board.notifyDropResource(v.getLocation(), v.activity);
        setChanged();
        notifyObservers(new MonitorInfo("clan" + clanResource.getType().name(), "" + clanResource.getAmount()));
    }

// OWN FUNCTIONS
    public boolean isTargetAvailable(Location targetSquare, Activity activity) {
        
        if (activity.equals(Activity.Hunter)) {
            return this.clanMemory.containsAnimals(targetSquare);
        } else {
            return this.clanMemory.contains(targetSquare) || this.squareQG.getLocation().compare(targetSquare);
        }

    }

    public Location getNewTarget(Activity activity, boolean goQG) {
        if (goQG) {
            //System.out.println("Target Defined : QG");
            return this.getSquareQG().getLocation();
        } else {
            //System.out.println("Target Defined : Other");
            Location l = clanMemory.getPOI(activity);
            /*if (l != null) {
                //l.displayInTerminal();
            } else {
                //System.out.println("No Target available in clan memory");
            }*/
            return l;
        }

    }

    public void addVillager(Villager villager) {
        villagerList.put(villager.getId(), villager);
    }

    public void displayInTerminal() {
        System.out.println("----------");
        System.out.println("clan : " + this.name);
        for (int i = 0; i < villagerList.size(); i++) {
            villagerList.get(1).displayInfoInTerminal();
        }
        System.out.println("----------");
    }

    // GETTER - SETTER
    public String getName() {
        return this.name;
    }

    public HashMap<Integer, Villager> getVillagerList() {
        return this.villagerList;
    }

    public HashMap<Integer, Building> getBuildingList() {
        return this.buildingList;
    }

    public ArrayList<Resource> getResourceList() {
        return this.resourceList;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setVillagerList(HashMap<Integer, Villager> villagerList) {
        this.villagerList = villagerList;
    }

    public void setBuildingList(HashMap<Integer, Building> buildingList) {
        this.buildingList = buildingList;
    }

    public void setResourceList(ArrayList<Resource> resourceList) {
        this.resourceList = resourceList;
    }

    public Square getSquareQG() {
        return squareQG;
    }

    public void setSquareQG(Square squareQG) {
        this.squareQG = squareQG;
    }

    public Board getBoard() {
        return board;
    }

    public void setBoard(Board board) {
        this.board = board;
    }

    //temp
    void setMemory(Memory memory) {
        this.clanMemory = memory;
    }

    Memory getMemory() {
        return this.clanMemory;
    }

    public Square debugGetSquare(DirectDirection dd, Location location) {
        switch (dd) {
            case North:
                location.setYPosition(location.getYPosition() - 1);
                break;
            case NorthEast:
                location.setXPosition(location.getXPosition() + 1);
                location.setYPosition(location.getYPosition() - 1);
                break;
            case East:
                location.setXPosition(location.getXPosition() + 1);
                break;
            case SouthEast:
                location.setXPosition(location.getXPosition() + 1);
                location.setYPosition(location.getYPosition() + 1);
                break;
            case South:
                location.setYPosition(location.getYPosition() + 1);
                break;
            case SouthWest:
                location.setXPosition(location.getXPosition() - 1);
                location.setYPosition(location.getYPosition() + 1);
                break;
            case West:
                location.setXPosition(location.getXPosition() - 1);
                break;
            case NorthWest:
                location.setXPosition(location.getXPosition() - 1);
                location.setYPosition(location.getYPosition() - 1);
                break;
        }

        return this.board.getSquareFromLocation(location);
    }

    public void reportLocation(Location target, Activity activity) {
        if (target == null) {
            System.out.println("Impossible to report null target");
            return;
        }

        Square s = board.getSquareFromLocation(target);
        boolean targetOK = false;

        if (s != null) {
            if (activity.equals(Activity.Hunter)) {
                if (s.getBeingReference() != null && s.getBeingReference().isAnimal() && s.getBeingReference().getResourceBrought().getAmount() > 0) {
                    targetOK = true;
                }
            } else {
                if (s.getResource() != null && s.getResource().getAmount() > 0) {
                    targetOK = true;
                }
            }
        }

        if (!targetOK) {
            //System.out.println("Target is not valid anymore, remove from memory");

            this.getMemory().remove(activity, target);
        }
    }

    public Memory getClanMemory() {
        return clanMemory;
    }
}
